package com.vains.config.bean;

import lombok.AllArgsConstructor;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.web.client.RestTemplate;

import javax.sql.DataSource;

@Order(-1)
@Configuration
@AllArgsConstructor
public class SecurityBeanConfig {

    private final DataSource dataSource;

    // private final RedisConnectionFactory redisConnectionFactory;

    /**
     * 令牌存储方式 这里是jdbc
     * @return tokenStore
     */
    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    /**
     * 从数据库中查询出客户端信息
     * @return JdbcClientDetailsService
     */
    @Bean
    public JdbcClientDetailsService jdbcClientDetailsService() {
        JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
        jdbcClientDetailsService.setPasswordEncoder(passwordEncoder());
        return jdbcClientDetailsService;
    }

    /**
     * 令牌管理方式
     * @return AuthorizationServerTokenServices
     */
    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setClientDetailsService(jdbcClientDetailsService());
        // 令牌存取通过 自定义tokenStore
        tokenServices.setTokenStore(tokenStore());
        // 设置支持刷新令牌
        tokenServices.setSupportRefreshToken(true);
        // 允许重复使用refresh token
        tokenServices.setReuseRefreshToken(true);

        /*// access token有效期2个小时
        tokenServices.setAccessTokenValiditySeconds(60 * 60 * 2);
        // refresh token有效期30天
        tokenServices.setRefreshTokenValiditySeconds(60 * 60 * 24 * 30);*/
        return tokenServices;
    }

    /**
     * 授权码存储方式 这里是 数据库
     * @return AuthorizationCodeServices
     */
    @Bean
    public AuthorizationCodeServices authorizationCodeServices() {
        return new JdbcAuthorizationCodeServices(dataSource);
    }

    /**
     * 设置密码加密方式
     * @return BCryptPasswordEncoder
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public ResourceServerTokenServices resourceServerTokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        // 设置支持刷新token
        tokenServices.setSupportRefreshToken(true);
        // 设置token存储方式
        tokenServices.setTokenStore(tokenStore());
        // 设置从数据库读取客户端信息
        tokenServices.setClientDetailsService(jdbcClientDetailsService());
        return tokenServices;
    }

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

}
